﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Configuration;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace GDoc.Data.Azure
{
    public class StorageContext
    {
        TableServiceContext context;
        CloudBlobClient blobClient;

        /// <summary>
        /// Once per lifetime at the first creation of the context, checks for tables.
        /// </summary>
        static StorageContext()
        {
            var storageAccount = CreateStorageAccount();
            var client = new CloudTableClient(storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);
            var blobClient = new CloudBlobClient(storageAccount.BlobEndpoint.AbsoluteUri, storageAccount.Credentials);

            //Initialize azure tables if not exists
            client.CreateTableIfNotExist(StorageContext.FileSystemSetName);

            //Initialize containers if not exists
            blobClient.GetContainerReference(StorageContext.FilesBlobContainerName).CreateIfNotExist();
        }

        /// <summary>
        /// Creates a new StorageContext.
        /// </summary>
        public StorageContext()
        {
            var storageAccount = CreateStorageAccount();
            context = new TableServiceContext(storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);
            blobClient = new CloudBlobClient(storageAccount.BlobEndpoint.AbsoluteUri, storageAccount.Credentials);
        }

        /// <summary>
        /// Create an Azure storage account using connection string from Azure if
        /// its available or from configuration (i.e. in tests).
        /// </summary>
        /// <returns>A new configured CloudStorageAccount</returns>
        private static CloudStorageAccount CreateStorageAccount()
        {
            CloudStorageAccount storageAccount;


            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
            {
                string connectionString;

                if (RoleEnvironment.IsAvailable)
                {
                    connectionString = RoleEnvironment.GetConfigurationSettingValue(configName);
                }
                else
                {
                    connectionString = ConfigurationManager.AppSettings[configName];
                }

                configSetter(connectionString);
            });

            if (RoleEnvironment.IsAvailable)
                storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
            else
                storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["DataConnectionString"]);
            return storageAccount;

        }

        /// <summary>
        /// Blob Container for report snapshots.
        /// </summary>
        public CloudBlobContainer Files
        {
            get
            {
                return blobClient.GetContainerReference(StorageContext.FilesBlobContainerName);
            }
        }

        /// <summary>
        /// Storage Set for an activity FileSystem.
        /// </summary>
        public StorageSet<FileSystemEntryAzure> FileSystem
        {
            get
            {
                return new StorageSet<FileSystemEntryAzure>(FileSystemSetName, context);
            }
        }

        //FileSystem azure table name
        private static string FileSystemSetName = "GDocFileSystem";

        private static string FilesBlobContainerName = "gdocfiles";
    }
}
